/*
	All calls of OutputLog() are just for an output for debuging purposes.
	They are just to make see if something went wrong, and has mostly only
	told me when somene banned has tried to log in.

	Files are defined in the .dme file so they can be called anything.
*/

proc
	// Temp
	ReturnKeyID(var/source as text)
		return ReturnID(source)

	// Return the ID of a player if their key exists
	ReturnID(var/source as text)
		var/savefile/Players = new(PLAYERS)
		Players.cd = "/"; Players.eof=-1
		var/count = 1

		while(count != Players["PlayerCount"]+1)
			if(source in Players["[count]"])
				return count
			count++

		return 0 // If it doesn't find the key, it returns zero.

	ReturnTelnetID(var/client/source)
		var/savefile/Chart = new(ARCHIVE)
		Chart.cd = "/"; Chart.eof=-1
		var/IPs = list()

		var/count = 1

		while(count != Chart["IDCount"]+1)
			IPs = Chart["[count]/IPs"]
			if(source.address in IPs)
				return count
			count++

		return 0

	// Returns a list of keys associated with a key
	ReturnKeys(target)
		var
			savefile/Chart = new(ARCHIVE)
			ID = ReturnID(target)
			Keys = Chart["[ID]/Keys"]
			output = ""

		for(var/K in Keys) output += "\"[K]\" "

		return output

	checkMute(target)
		var
			savefile/Chart = new(ARCHIVE)
		Chart.cd = "/"; Chart.eof=-1

		var/ID = ReturnID(target)

		if(ID == 0) return 0
		else
			return Chart["[ID]/Muted"]

	checkBan(target)
		var
			savefile/Chart = new(ARCHIVE)
		Chart.cd = "/"; Chart.eof=-1

		var/ID = ReturnID(target)

		if(ID == 0) return 0
		else
			return Chart["[ID]/Banned"]


client/proc

	// Add the "Value" to "Type" for "ID"
	// Called when a person has a new IP, Key, or CID, and already has an ID.
	AddInfo(ID, Type, Value)
		var/savefile/Chart = new(ARCHIVE)
		var/savefile/Players = new(PLAYERS)

		var/list/NewList = list()
		Chart["[ID]/[Type]s"] = list()
		var/Found = 0

		for(var/C in Chart["[ID]/[Type]s"])
			if(C == Value) Found = 1

		if(!Found)
			OutputLog(BLUE,"Adding [Type] of [Value] to [ID]")
			NewList = Chart["[ID]/[Type]s"]
			NewList.Add(Value)
			Chart["[ID]/[Type]s"] = NewList

		if(Type=="Key")
			Players["[ID]"] = Chart["[ID]/Keys"]



	// Return if an ID is muted or not globally
	IsMuted()
		var/savefile/Chart = new(ARCHIVE)
		var/ID = ReturnID(src.key)

		if(src.ckey in MuteList) return 1
		if(ID == 0) OutputLog(RED,"WARNING -- ID of [src.key] is 0 when checking IsMuted()")
		else if(Chart["[ID]/Muted"] == 1) return 1
		else return 0



	// Return if an ID is banned or not globally
	IsBanned()
		var/savefile/Chart = new(ARCHIVE)
		var/ID = ReturnID(src.key)

		//if(ID == 0) ID = ReturnTelnetID(src)

		if(ID == 0)
			OutputLog(RED,"WARNING -- ID of [src.key] is 0 when checking IsBanned() -- Disconnecting User")
			System_UserMessage(src,"There was a problem with your ID, please contact Mikau about the problem.")
			sleep(3)
			del(src)

		if(Chart["[ID]/Banned"] == 1)
			OutputLog(RED,"IsBanned() for [src.key] has returned true.")
			return 1

		if(src.ckey in Banned)
			OutputLog(RED,"IsBanned() for [src.key] has returned true. {fallback}")
			return 1

		return 0


	// Add an initial archive for a user (Do not call this)
	NewUser()
		set hidden = 1

		/*********************/
		//  ACTUAL ARCHIVES  //
		/*********************/
		var/savefile/Chart = new(ARCHIVE)

		if(Chart["IDCount"] <= 1) Chart["IDCount"] = Chart["IDCount"] + 1
		var/ID = Chart["IDCount"]

		//Create the lists
		var/list
			Keys = list()

		// Create empty lists
		Chart["[ID]/Keys"] = list()
		Chart["[ID]/IPs"] = list()
		Chart["[ID]/CIDs"] = list()

		// Add the initial values to the lists.
		AddInfo(ID,"Key",src.key)
		AddInfo(ID,"IP",src.address)
		AddInfo(ID,"CID",src.computer_id)

		OutputLog(BLUE,"[src.key] has been archived as [ID].")

		// Other information
		Chart["[ID]/Joined"] = time2text(world.timeofday,"Day Month DD, YYYY. (hh:mm:ss EST)")
		Chart["[ID]/Muted"] = 0
		Chart["[ID]/Banned"] = 0

		Chart["[ID]/Notes"] = "There are currently no notes on this person."
		Chart["[ID]/Punishments"] = 0


		/*********************/
		//  ID ONLY ARCHIVE  //
		/*********************/

		Keys.Add("[src.key]")
		var/savefile/Players = new(PLAYERS)
		Players["[ID]"] = Keys
		Players["PlayerCount"] = ID


	// Always call this to create or update an entry
	// Call this on login so that information for every person is always up to date
	UpdateArchive()
		OutputLog(RED, "[src.key] has connected from [src.computer_id] @ [src.address].")
		var/savefile/Chart = new(ARCHIVE)
		Chart.cd = "/"; Chart.eof=-1
		var
			Found = 0
			ID = 0

		// If there is no chart, start it off with this player
		if(!Chart["IDCount"])
			Chart["IDCount"] = 0
			src.NewUser()

		// Time to check for a person, and update their information.
		else

			// Try to find the persons ID
			if(src.IsTelnet())
				ID = ReturnTelnetID(src)
			else
				ID = ReturnID(src.key)

			OutputLog(NORMAL,"Searching for [src.key]'s ID -- Found [ID]")

			// If the person has an ID
			if(ID != 0)

				if(!(src.key in Chart["[ID]/Keys"]))
					AddInfo(ID,"Key",src.key)

				// Check for the IP
				if(!(src.address in Chart["[ID]/IPs"]))
					AddInfo(ID,"IP",src.address)

				// Check for the CID
				if(!src.IsTelnet())
					if(!(src.computer_id in Chart["[ID]/CIDs"]))
						AddInfo(ID,"CID",src.computer_id)

			else

				// Check for similar IP addresses or CIDs in the archives
				for(var/i = 1; i <= Chart["IDCount"]; i++)

					if(src.address in Chart["[i]/IPs"])
						AddInfo(i,"Key",src.key)
						if(!src.IsTelnet()) AddInfo(i,"CID",src.computer_id)
						Found = 1

					else if(src.computer_id in Chart["[i]/CIDs"] && !src.IsTelnet())
						AddInfo(i,"Key",src.key)
						AddInfo(i,"IP",src.address)
						Found = 1

					else if(src.key in Chart["[ID]/Keys"])
						AddInfo(i,"IP",src.address)
						if(!src.IsTelnet()) AddInfo(i,"CID",src.computer_id)

					if(Found) break

				if(!Found)
					src.NewUser()


	// ADMIN
	AddPunishment(Admin, Player, Type)
		set hidden = 1
		set category = "Admin"

		var/savefile/Chart = new(ARCHIVE)
		var/savefile/Players = new(PLAYERS)
		var/savefile/Punishments = new(PUNISH)


		var
			count = 0
			ID = 0
			Entry = 0

		for(var/C in Players)
			count++
			if(Player in Players["[count]"])
				ID = count
				break

		if(ID == 0)
			OutputLog(RED,"ID for [Player] is 0, falling back to internal system to [Type].")
			if(Type == "Mute")
				MuteList+=Player
			else if(Type == "Ban")
				Banned+=Player
			else if(Type == "Unmute")
				MuteList-=Player
			else if(Type == "Unban")
				Banned-=Player
			else if(Type == "Kick")
				var/client/person = findTarget(Player)
				del(person)
		else

			///////////////
			Punishments["[ID]/Keys"] = Chart["[ID]/Keys"]

			if(Type == "Mute")
				Chart["[ID]/Muted"] = 1
				Punishments["[ID]/Muted"] = 1
				MuteList+=Player
				Entry = 1


			else if(Type == "Unmute")
				Chart["[ID]/Muted"] = 0
				Punishments["[ID]/Muted"] = 0
				MuteList-=Player

			else if(Type == "Ban")
				Chart["[ID]/Banned"] = 1
				Punishments["[ID]/Banned"] = 1
				Entry = 1
				Banned+=Player
				for(var/client/C in Everyone)
					if(C.key in Chart["[ID]/Keys"])
						var/client/person = findTarget(C.key)
						person.Kicked = TRUE
						del(person)

			else if(Type == "Unban")
				Chart["[ID]/Banned"] = 0
				Punishments["[ID]/Banned"] = 0
				Banned-=Player

			else if(Type == "Kick")
				for(var/client/C in Everyone)
					if(C.key in Chart["[ID]/Keys"])
						var/client/person = findTarget(C.key)
						person.Kicked = TRUE
						del(person)
				Entry = 1

			OutputLog(RED,"ID of [ID] has been issued \"[Type]\".")
			///////////////

			if(Entry)
				var/p = Chart["[ID]/Punishments"]+1
				Chart["[ID]/Punishments"] = p
				Chart["[ID]/Punishment[p]/Admin"] = Admin
				Chart["[ID]/Punishment[p]/Player"] = Player
				Chart["[ID]/Punishment[p]/Type"] = Type
				Chart["[ID]/Punishment[p]/Date"] = time2text(world.timeofday,"Day Month DD, YYYY. (hh:mm:ss EST)")

				Punishments["[ID]/Punishments"] = p

			if(Type != "Kick") ViewID(ID)

client/verb
	FindID()
		set hidden = 1
		if(!(src.ckey in Admins)) return
		var/savefile/Players = new(PLAYERS)
		var/savefile/Chart = new(ARCHIVE)
		var/txtfile = file(PTEXT)
		var/txtfile2 = file(CTEXT)

		fdel(txtfile)
		Players.ExportText("/",txtfile)
		fdel(txtfile2)
		Chart.ExportText("/",txtfile2)

		src<<browse(txtfile,"window=1")

	ViewPunishments(var/id as num|null)
		set hidden = 1
		if(!(src.ckey in Admins)) return
		var/ID = 0
		if(id) ID = id

		var/savefile/Chart = new(ARCHIVE)

		var
			style = "font-weight: bold; font-size: 12px;"
			style2 = "text-align: center;"
			row = 1
			punishments = Chart["[ID]/Punishments"]

		// Header
		src<<output("<span style=\"[style][style2]\">Admin</span>","Admin_ArchivePunishments.punishgrid:1,[row]")
		src<<output("<span style=\"[style][style2]\">Key</span>","Admin_ArchivePunishments.punishgrid:2,[row]")
		src<<output("<span style=\"[style][style2]\">Type</span>","Admin_ArchivePunishments.punishgrid:3,[row]")
		src<<output("<span style=\"[style][style2]\">Date</span>","Admin_ArchivePunishments.punishgrid:4,[row]")
		row++

		for(var/i = 1; i<=punishments; i++)
			src<<output("<span style=\"[style2]\">[Chart["[ID]/Punishment[i]/Admin"]]</span>","Admin_ArchivePunishments.punishgrid:1,[row]")
			src<<output("<span style=\"[style2]\">[Chart["[ID]/Punishment[i]/Player"]]</span>","Admin_ArchivePunishments.punishgrid:2,[row]")
			src<<output("<span style=\"[style2]\">[Chart["[ID]/Punishment[i]/Type"]]</span>","Admin_ArchivePunishments.punishgrid:3,[row]")
			src<<output("<span style=\"[style2]\">[Chart["[ID]/Punishment[i]/Date"]]</span>","Admin_ArchivePunishments.punishgrid:4,[row]")
			row++

		winset(src,"Admin_ArchivePunishments.punishgrid","cells=4x[row-1]")
		winset(src,"Admin_ArchivePunishments","is-visible=true")

	adminViewPunishmentsButton()
		set hidden = 1
		if(!(src.ckey in Admins)) return
		var/ID = winget(src,"Admin_ArchiveEntry.ID","text")
		ViewPunishments(ID)

	adminSaveNotesButton()
		set hidden = 1
		if(!(src.ckey in Admins)) return
		var/ID = winget(src,"Admin_ArchiveEntry.ID","text")
		var/Notes = winget(src,"Admin_ArchiveEntry.Notes","text")
		var/savefile/Chart = new("server/Archives/Chart.sav")
		Chart["[ID]/Notes"] = Notes

	ViewID(var/id as num|null)
		set hidden = 1
		if(!(src.ckey in Admins)) return

		var/ID = 0
		if(id) ID = id
		else ID = winget(src,"Admin_Settings.idinput","text")

		var/savefile/Chart = new(ARCHIVE)

		var
			Keys = list()
			IPs = list()
			CIDs = list()

		var
			Joined = Chart["[ID]/Joined"]
			Muted = Chart["[ID]/Muted"]
			Banned = Chart["[ID]/Banned"]
			Punishments = Chart["[ID]/Punishments"]
			Notes = Chart["[ID]/Notes"]

		Keys = Chart["[ID]/Keys"]
		IPs = Chart["[ID]/IPs"]
		CIDs = Chart["[ID]/CIDs"]

		if(Muted == 1) Muted = "Yes"
		else Muted = "No"

		if(Banned == 1) Banned = "Yes"
		else Banned = "No"

		winset(src,"Admin_ArchiveEntry.ID","text=\"[ID]\"")
		winset(src,"Admin_ArchiveEntry.Muted","text=\"[Muted]\"")
		winset(src,"Admin_ArchiveEntry.Joined","text=\"  [Joined]\"")
		winset(src,"Admin_ArchiveEntry.Banned","text=\"[Banned]\"")
		winset(src,"Admin_ArchiveEntry.Punishments","text=\"[Punishments]\"")

		src<<output(null,"Admin_ArchiveEntry.Keys")
		src<<output(null,"Admin_ArchiveEntry.IPs")
		src<<output(null,"Admin_ArchiveEntry.CIDs")

		for(var/K in Keys) src<<output(K,"Admin_ArchiveEntry.Keys")
		for(var/I in IPs) if(I != null) src<<output(I,"Admin_ArchiveEntry.IPs")
		for(var/C in CIDs) if(C != null) src<<output(C,"Admin_ArchiveEntry.CIDs")

		winset(src,"Admin_ArchiveEntry.Notes","text=\"[Notes]\"")

		winset(src,"Admin_ArchiveEntry","size=495x575")
		winset(src,"Admin_ArchiveEntry","is-visible=true")